package com.guaoran.micro.services.spring.cloud.client.controller;

import com.guaoran.micro.services.spring.cloud.client.annotation.CustomizedLoadBalanced;
import com.guaoran.micro.services.spring.cloud.client.loadbalance.LoadBalancedRequestInterceptor;
import com.guaoran.micro.services.spring.cloud.client.service.feign.clients.SayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.util.Arrays;
import java.util.Collection;

/**
 * @author : gucheng
 * @Description : <br/>
 *  使用注解方式负载均衡方式
 * @date :2018/12/2 13:00
 */
@RestController
@RequestMapping("/lb/cust")
public class ClientLoadBalancedCustomizedController {
    @Value("${spring.application.name}")
    private String currentServiceName;
    //采用自定义
    @Autowired
    @CustomizedLoadBalanced
    private RestTemplate restTemplate;

    //采用Ribbon方式实现负载均衡
    @Autowired
    @LoadBalanced
    private RestTemplate lbRestTemplate;


    @Autowired
    private SayService sayService;


    /**
     * 采用自定义拦截实现负载均衡
     * @param serviceName
     * @param message
     * @return
     */
    @GetMapping("/invoke/{serviceName}/say")
    public String invokeSay(@PathVariable String serviceName,
                            @RequestParam String message) {
        return restTemplate.getForObject("/" + serviceName + "/say?message=" + message, String.class);
    }

    /**
     * 采用Ribbon 负载均衡实现
     * @param serviceName
     * @param message
     * @return
     */
    @GetMapping("/lb/invoke/{serviceName}/say")
    public String lbInvokeSay(@PathVariable String serviceName,
                            @RequestParam String message) {
        return lbRestTemplate.getForObject("http://" + serviceName + "/say?message=" + message, String.class);
    }

    /**
     * feign 服务调用demo
     * @param message
     * @return
     */
    @GetMapping("/feign/say")
    public String feignSay(@RequestParam String message) {
        return sayService.say(message);
    }

    /**
     * 自定义拦截器
     * @return
     */
    @Bean
    public ClientHttpRequestInterceptor interceptor (){
        return new LoadBalancedRequestInterceptor();
    }

    /**
     * 使restTemplate走自定义的拦截器
     * @return
     */
    @Bean
    @CustomizedLoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    /**
     * 使用Ribbon负载均衡
     * @return
     */
    @Bean
    @LoadBalanced
    public RestTemplate getLbRestTemplate() {
         return new RestTemplate();
    }
    @Bean
    @Autowired
    public Object customizedObject(@CustomizedLoadBalanced Collection<RestTemplate> restTemplates,ClientHttpRequestInterceptor interceptor){
        restTemplates.forEach(ret->{
            ret.setInterceptors(Arrays.asList(interceptor));
        });
        return new Object();
    }
}
